﻿using Api.Shared.Model;
using Api.Shared.Model.Common;
using Api.Shared.Model.Impl;
using Api.Shared.Model.Yanji;
using Api.Shared.MyPlc.S7;
using Api.Shared.Responsitory.Sqlite;
using Api.Shared.Sugar;
using Api.Shared.WebSocket;
using Microsoft.AspNetCore.SignalR;
using System.Text.Json;
using static Api.Shared.Utils.MyCopyProperty;

namespace FitterTest
{
    public class StartupInitializationService : IHostedLifecycleService
    {
        private readonly IS7ConnService s7ConnService;
        private DB33Ioc dB33Ioc;
        private readonly ILogger<StartupInitializationService> logger;
        private readonly SqliteSTRespository<Person> repPerson;
        private readonly IHttpClientFactory clientFactory;
        private readonly IConfiguration configuration;
        private readonly Db93Alarm db93Alarm;
        private readonly Db95DeviceHis db95DeviceHis;
        private readonly ISugarClientService helper;
        private readonly IHubContext<MyHub> hubContext;
        private WebSocketTest webSocketTest = new();

        public StartupInitializationService(
            IS7ConnService s7ConnService,
            DB33Ioc dB33Ioc,
            ILogger<StartupInitializationService> logger,
            SqliteSTRespository<Person> repPerson,
            IHttpClientFactory clientFactory,
            IConfiguration configuration,
            Db93Alarm db93Alarm,
            Db95DeviceHis db95DeviceHis,
            [FromKeyedServices(nameof(SqlName.sqliteST))] ISugarClientService helper,
            IHubContext<MyHub> hubContext
        )
        {
            this.s7ConnService = s7ConnService;
            this.dB33Ioc = dB33Ioc;
            this.logger = logger;
            this.repPerson = repPerson;
            this.clientFactory = clientFactory;
            this.configuration = configuration;
            this.db93Alarm = db93Alarm;
            this.db95DeviceHis = db95DeviceHis;
            this.helper = helper;
            this.hubContext = hubContext;
        }

        ///// <summary>
        ///// 第二早
        ///// </summary>
        public Task StartedAsync(CancellationToken cancellationToken)
        {
            //string ip = configuration["PlcIp"]?? "192.168.1.11";
            //s7ConnService.ConnPlc(ip, 33, 0);

            try
            {
                //s7ConnService.ConnPlc(ip);
            }
            catch (Exception ex)
            {
                logger.LogError($"网络错误:{ex.Message}");
                return Task.CompletedTask;
            }
            logger.LogWarning("初始化函数成功");

            // 使用MyHub建立长连接，每1秒推送随机整数
            //StartRandomPushToHub();

            //AlarmFunc();
            //KaijiTimeFunc();

            return Task.CompletedTask;
        }

        private void StartRandomPushToHub()
        {
            // 假设MyHub为SignalR Hub，IHubContext<MyHub>已通过依赖注入获得
            // 你需要在构造函数中注入IHubContext<MyHub> hubContext
            // private readonly IHubContext<MyHub> hubContext;
            // 并在Program.cs中注册SignalR服务和MyHub

            _ = Task.Run(async () =>
            {
                var random = new Random();
                while (true)
                {
                    int value = random.Next(0, 10000);
                    webSocketTest.TestInt1 = value;
                    webSocketTest.TestInt1 = value + 1;
                    webSocketTest.TestFloat1 = value + 2.1f;

                    // 序列化 webSocketTest 为字符串，使用自定义配置
                    var options = new JsonSerializerOptions
                    {
                        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                        WriteIndented = true
                    };
                    string wsTestJson = JsonSerializer.Serialize(webSocketTest, options);

                    try
                    {
                        await hubContext.Clients.All.SendAsync("ReceiveRandomNumber", wsTestJson);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"推送随机数失败: {ex.Message}");
                    }
                    await Task.Delay(1000);
                }
            });
        }

        private void KaijiTimeFunc()
        {
            db95DeviceHis.PropertyChanged += async (s, e) =>
            {
                if (e.PropertyName == "Kr16Trigger")
                {
                    var d = new DeviceHis();
                    CopyProperties(db95DeviceHis, d);
                    var cont = await helper.Db.Insertable<DeviceHis>(d).ExecuteCommandAsync();
                }
            };
        }

        private void AlarmFunc()
        {
            MyAlarm myAlarm = new();
            db93Alarm.PropertyChanged += async (s, e) =>
            {
                switch (e.PropertyName)
                {
                    case "Word1_1":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_1}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_1}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_2":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_2}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_2}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_3":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_3}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_3}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_4":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_4}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_4}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_5":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_5}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_5}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_6":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_6}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_6}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_7":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_7}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_7}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_8":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_8}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_8}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_9":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_9}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_9}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_10":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_10}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_10}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_11":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_11}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_11}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_12":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_12}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_12}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_13":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_13}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_13}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_14":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_14}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_14}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_15":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_15}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_15}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word1_16":
                        logger.LogWarning($"{AlarmConst.AlarmWord1_16}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord1_16}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_1":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_1}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_1}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_2":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_2}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_2}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_3":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_3}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_3}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_4":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_4}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_4}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_5":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_5}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_5}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_6":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_6}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_6}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_7":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_7}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_7}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_8":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_8}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_8}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_9":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_9}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_9}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_10":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_10}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_10}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_11":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_11}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_11}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_12":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_12}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_12}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_13":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_13}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_13}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_14":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_14}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_14}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_15":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_15}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_15}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    case "Word2_16":
                        logger.LogWarning($"{AlarmConst.AlarmWord2_16}");
                        await helper
                            .Db.Insertable(
                                new MyAlarm()
                                {
                                    AlarmMessage = $"{AlarmConst.AlarmWord2_16}",
                                    InsertTime = DateTime.Now
                                }
                            )
                            .ExecuteCommandAsync();
                        break;
                    default:
                        break;
                }
            };
        }

        ///// <summary>
        ///// 最早
        ///// </summary>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        public Task StartingAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        public Task StoppedAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        public Task StoppingAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            //IConfigurationRoot? buider = new ConfigurationBuilder()
            //    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            //    .Build();
            //string ip = buider["PlcIp"];

            //string ip = configuration["PlcIp"];
            //s7ConnService.ConnPlc(ip, 33, 0);

            //dB33Ioc.PropertyChanged += async (s, e) =>
            //{
            //    if (e.PropertyName == "B2")
            //    {
            //        logger.LogWarning("B2被触发!");
            //        logger.LogWarning(dB33Ioc.Str);
            //    }
            //};

            //List<Person> persons = new();
            //for (int i = 0; i < 2; i++)
            //{
            //    Person person = new()
            //    {
            //        Age = $"{i + 1}",
            //        Name = $"Tom{i + 1}"
            //    };
            //    persons.Add(person);
            //}

            //var a = repPerson.InsertRange(persons);

            //logger.LogWarning(respositoryFt.GetById(1).PartNum);

            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        ///// <summary>
        ///// 第二早
        ///// </summary>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        //public Task StartAsync(CancellationToken cancellationToken)
        //{
        //    //IConfigurationRoot? buider = new ConfigurationBuilder()
        //    //    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        //    //    .Build();
        //    //string ip = buider["PlcIp"];
        //    string ip = configuration["PlcIp"];
        //    s7ConnService.ConnPlc(ip, 33, 0);

        //    dB33Ioc.PropertyChanged += async (s, e) =>
        //    {
        //        if (e.PropertyName == "B2")
        //        {
        //            logger.LogWarning("B2被触发!");
        //            logger.LogWarning(dB33Ioc.Str);
        //        }
        //    };

        //    //List<Person> persons = new();
        //    //for (int i = 0; i < 2; i++)
        //    //{
        //    //    Person person = new()
        //    //    {
        //    //        Age = $"{i + 1}",
        //    //        Name = $"Tom{i + 1}"
        //    //    };
        //    //    persons.Add(person);
        //    //}

        //    //var a = repPerson.InsertRange(persons);

        //    //logger.LogWarning(respositoryFt.GetById(1).PartNum);

        //    return Task.CompletedTask;
        //}

        ///// <summary>
        ///// 停止后第二
        ///// </summary>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        //public Task StopAsync(CancellationToken cancellationToken)
        //{
        //    return Task.CompletedTask;
        //}

        ///// <summary>
        ///// 启动完成
        ///// </summary>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        //async Task IHostedLifecycleService.StartedAsync(CancellationToken cancellationToken)
        //{
        //    using HttpClient? client = clientFactory.CreateClient();
        //    client.Timeout = TimeSpan.FromSeconds(20);
        //    //client.BaseAddress = new Uri(ip);

        //    var baseRequest = new BaseRequest
        //    {
        //        Method = HttpMethod.Post,
        //        Route = "/api/Test/MyClientTest",
        //        Parameter = new Person { Age = "19", Name = "xiaoM" }
        //    };
        //    //MyHttpClient myHttpClient = new(ip, client);
        //    MyHttpClient myHttpClient = new(client, "myIp");
        //    var response = await myHttpClient.ExecuteAsync<Person>(baseRequest);
        //    JsonSerializerOptions options = new()
        //    {
        //        WriteIndented = true,
        //        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        //    };
        //    var str = JsonSerializer.Serialize(response, options);
        //    logger.LogInformation($"started返回值: {str}");
        //    //double ac = 0;
        //    //int aaa = 0;
        //    //short bbb = 0;
        //    //Interlocked.Exchange(ref ac, 1.5);
        //    //Interlocked.Exchange(ref aaa , bbb);
        //    return;
        //}

        ///// <summary>
        ///// 最早
        ///// </summary>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        //Task IHostedLifecycleService.StartingAsync(CancellationToken cancellationToken)
        //{
        //    return Task.CompletedTask;
        //}

        ///// <summary>
        ///// 已经停止
        ///// </summary>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        //Task IHostedLifecycleService.StoppedAsync(CancellationToken cancellationToken)
        //{
        //    return Task.CompletedTask;
        //}

        ///// <summary>
        ///// 停止后第一
        ///// </summary>
        ///// <param name="cancellationToken"></param>
        ///// <returns></returns>
        //Task IHostedLifecycleService.StoppingAsync(CancellationToken cancellationToken)
        //{
        //    return Task.CompletedTask;
        //}
    }
}
